var http = require('http');
var fs = require('fs');
/**
 * [内置的PATH模块提供了与文件系统路径相关的功能]
 * @path {[Object]}
 */
var path = require('path');
/**
 * [第三方的mime模块有根据文件的扩展名得出mime类型的能力]
 * @mime {[Object]}
 */
var mime = require('mime');

/**
 * [cache是用来缓存文件内容的对象]
 * @type {Object}
 */
var cache = {};

/**
 * [send404 在所请求的文件不存在的时候发送404的错误]
 * @param  {[Object]} response [响应请求的对象]
 * @return {[undefine]}          [description]
 */
function send404(response) {
	response.writeHead(404, {
		'Content-Type' : 'text-palin'
	});
	response.write('Error 404, reource not found');
	response.end();
} 
/**
 * [sendFile 提供文件传输服务]
 * @param  {[Object]} response     [响应请求的对象]
 * @param  {[String]} filePath     [资源的路径，相对于根路径]
 * @param  {[String]} fileContents [资源名]
 * @return {[undefine]}              [description]
 */
function sendFile(response, filePath, fileContents) {
	response.writeHead(200, {
		'Content-Type' : mime.lookup(path.basename(filePath))
	});
	response.end(fileContents);
}

function serveStatic(response, cache, absPath) {
	if (cache[absPath]) {    //检查文件是否缓存在内存中
		sendFile(response, absPath, cache[absPath]);  // 如果在内存中，则从内存中返回文件
	} else {
		fs.exists(absPath, function(exists) {  // 检查文件是否存在
			if (exists) {
				fs.readFile(absPath, function(err, data) {  // 存在则从硬盘读取文件
					if (err) {
						send404(response);
					} else {
						cache[absPath] = data;  // 把从硬盘中读取的文件缓冲到内从中
						sendFile(response, absPath, data); // 把读取到的文件返回
					}
				});
			} else {
				send404(response);  // 发送404响应
			}
		});
	}
}


//  创建http服务器的逻辑

var server = http.createServer(function(request, response) {  // 创建http服务器，用匿名函数来定义对每个请求的处理行为
	var filePath = false;
	if (request.url == '/') {
		filePath = 'public/index.html'; // 确认返回的默认html文件
	} else {
		filePath = 'public' + request.url; // 将URL路径转换为文件的相对路径
	}
	var absPath = './' + filePath; 
	serveStatic(response, cache, absPath); // 返回静态文件
})

// 启动serever

server.listen(3000, function() {
	console.log('Server listening on port 3000');
});


// 设置socket.io服务器
var chatServer = require('./lib/chat_server'); // 定制的node模块，它提供的逻辑是用来处理基于socket.io的服务端的聊天功能

chatServer.listen(server);  // 启动socket.io服务器，给它提供一个已经定义好的HTTP服务器，这样它就能跟HTTP服务器共享同一个TCP/IP端口了
